namespace SimpleWebServices.Models
{
    using System.Xml.XPath;
    using SimpleWebServices;
    using SimpleWebServices.Security.Cryptography;
    using SimpleWebServices.Web;
    using Xunit;

    public sealed class OrganizationFacts
    {
        [Fact]
        public void typedef()
        {
            Assert.True(new ObjectExpectations<Organization>()
                .DerivesFrom<Resource>()
                .IsConcreteClass()
                .IsUnsealed()
                .HasDefaultConstructor()
                .XmlRoot("organization")
                .Result);
        }

        [Fact]
        public void deserialize()
        {
            Organization actual = (
                "<organization acronym='EX' title='Example'>" +
                    "<contacts>" +
                        "<contact />" +
                    "</contacts>" +
                "</organization>").Deserialize<Organization>();

            Assert.NotNull(actual);

            Assert.Equal<string>("EX", actual.Acronym);
            Assert.Equal<string>("Example", actual.Title);
            Assert.NotEmpty(actual.Contacts);
        }

        [Fact]
        public void deserializeEmpty()
        {
            Organization expected = new Organization();
            Organization actual = "<organization />".Deserialize<Organization>();

            Assert.NotNull(actual);

            Assert.Null(actual.Acronym);
            Assert.NotNull(actual.Contacts);
        }

        [Fact]
        public void serialize()
        {
            Organization obj = new Organization
            {
                Acronym = "EX",
                Title = "Example",
                Contacts = new ContactCollection
                {
                    new Contact()
                }
            };

            XPathNavigator navigator = obj.Serialize().CreateNavigator();

            Assert.True((bool)navigator.Evaluate("1=count(/organization)"));
            Assert.True((bool)navigator.Evaluate("1=count(/organization[@acronym='EX'][@title='Example'])"));
            Assert.True((bool)navigator.Evaluate("1=count(/organization/contacts/contact)"));
        }

        [Fact]
        public void ctor()
        {
            Assert.NotNull(new Organization());
        }

        [Fact]
        public void prop_Acronym()
        {
            Assert.True(new PropertyExpectations(typeof(Organization).GetProperty("Acronym"))
                .XmlAttribute("acronym")
                .IsAutoProperty<string>()
                .Result);
        }

        [Fact]
        public void prop_Contacts()
        {
            Assert.True(new PropertyExpectations(typeof(Organization).GetProperty("Contacts"))
                .XmlElement("contacts")
                .TypeIs<ContactCollection>()
                .DefaultValueIsNotNull()
                .Result);
        }

        [Fact]
        public void prop_Entity()
        {
            Assert.True(new PropertyExpectations(typeof(Organization).GetProperty("Entity"))
                .XmlIgnore()
                .TypeIs<string>()
                .DefaultValueIsNotNull()
                .Result);
        }

        [Fact]
        public void prop_Entity_get()
        {
            Organization obj = (
                "<organization acronym='EX' name='Example'>" +
                    "<contacts>" +
                        "<contact />" +
                    "</contacts>" +
                "</organization>").Deserialize<Organization>();

            string expected = "RceKRE19hQiKso+TmRC/0A==";
            string actual = MD5Hash.Compute(obj.Entity);

            Assert.Equal<string>(expected, actual);
        }

        [Fact]
        public void prop_Entity_getEmpty()
        {
            string expected = string.Empty;
            string actual = new Organization().Entity;

            Assert.Equal<string>(expected, actual);
        }
    }
}